一个运行的Android应用至少有2个ClassLoader,一个是BootClassLoader(系统启动时创建的),一个是PathClassLoader(应用启动时创建的,用于加载/data/data/packagename/apkname.apk)
android中应用的类加载器主要有两种,分别是PathClassLoader和DexClassLoader,PathClassLoader只能用来加载已安装应用的dex文件,而DexClassLoader可以用来加载未安装的apk\jar等文件;
PathClassLoder
1 | /** |
PathClassLoader是ClassLoader的简单实现且只能加载本地的列表文件或目录,在Android中也就是已安装好的APK,它不能加载来自网络的类。Android中的系统类加载器与应用类加载器都是PathClassLoader。
PathClassLoader是ClassLoader的简单实现且只能加载本地的列表文件或目录,在Android中也就是已安装好的APK,它不能加载来自网络的类。Android中的系统类加载器与应用类加载器都是PathClassLoader。
Android系统使用PathClassLoader来加载系统类和应用程序的类,如果是加载非系统应用程序类,则会加载data/app/目录下的dex文件以及包含dex的apk文件或jar文件,不管是加载那种文件,最终都是要加载dex文件,在这里为了方便理解,我们将dex文件以及包含dex的apk文件或jar文件统称为dex相关文件。PathClassLoader不建议开发直接使用。PathClassLoader继承自BaseDexClassLoader,很明显PathClassLoader的方法实现都在BaseDexClassLoader中。从PathClassLoader的构造方法也可以看出它遵循了双亲委托模式。
dexPath:包含dex文件的JAR/ZIP/APK文件的路径
librarySearchPath:native library文件的路径
parent:父类加载器
DexClassLoader
1 | /** |
DexClassLoader可以从包含dex文件的JAR或APK中来加载类,而这些代码源允许不必是安装应用的一部分,因此可用于动态加载。
构造方法中有一个新的参数为optimizedDirectory,它表示优化后的dex文件要写入的路径。通常建议使用如下路径:
context.getCodeCacheDir();
总结
- PathClassLoader: 主要用于系统和app的类加载器,其中optimizedDirectory为null, 采用默认目录/data/dalvik-cache/
- DexClassLoader: 可以从包含classes.dex的jar或者apk中,加载类的类加载器, 可用于执行动态加载,但必须是app私有可写目录来缓存odex文件. 能够加载系统没有安装的apk或者jar文件, 因此很多插件化方案都是采用DexClassLoader;
- BaseDexClassLoader: 比较基础的类加载器, PathClassLoader和DexClassLoader都只是在构造函数上对其简单封装而已.